/*  -*- mode: c++; coding: utf-8; c-file-style: "stroustrup"; -*-

    Copyright 2008 Asier Aguirre <asier.aguirre@gmail.com>
    This file is part of Intromit.

    Intromit is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Intromit is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Intromit.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef GENDATA_HH
#define GENDATA_HH
//! \defgroup gendata Gendata generator
//@{

#include "gendata_common.hh"

// DECLARATIONS
class metadata;
class string_index;
struct dwarf_base;

// CLASSES

//! Intromit generator plug-in to convert metadata into an array of integers
class gendata
{
    metadata *meta;
    string_index *doc;

    // generated data
    int *data, n_data, max_data;
    int i_data;

    // type remap
    int *type_remap, n_type_remap;

    // PRIVATE FUNCTIONS
    void write(int value);
    void write_string(int i_str);
    void write_comment();
    void write_location();
    void write_linkage();
    void write_vtable_linkage();
    void write_upper_bound();
    void write_const_value();
    void write_type();
    void write_child_number();
    void write_vtable();
    dwarf_base *get_base();
    void write_to_file(int i_out=0);
    void correct_var_fields_relativize_type();
    void correct_var_fields_relativize_type_recur(int &i, int pos_var_value);
    void dump(int i_out=1);
    void dump_recur(int &i, FILE *out, int level=0);

public:
    gendata(metadata *meta);
    ~gendata();

    int init_pass();
    int write_struct(gendata_type type);
};

// INTERFACE
extern "C"
{
    //! @name Initialization, finalization and navigation functions
    //@{
    int gendata_init(metadata *meta);
    int gendata_finish(metadata *meta);
    int gendata_next(metadata *meta);
    int gendata_down(metadata *meta);
    int gendata_up(metadata *meta);
    int gendata_type_recur(metadata *meta);
    int gendata_init_pass(metadata *meta);
    int gendata_finish_pass(metadata *meta); //@}

    //! @name Metadata specific types generation functions
    //@{
    int gendata_class(metadata *meta);
    int gendata_inheritance(metadata *meta);
    int gendata_method(metadata *meta);
    int gendata_member(metadata *meta);
    int gendata_member_vector_n_max(metadata *meta);
    int gendata_member_object(metadata *meta);
    int gendata_parameter(metadata *meta);
    int gendata_charp(metadata *meta);
    int gendata_const_charp(metadata *meta);
    int gendata_int(metadata *meta);
    int gendata_uint(metadata *meta);
    int gendata_short(metadata *meta);
    int gendata_ushort(metadata *meta);
    int gendata_float(metadata *meta);
    int gendata_double(metadata *meta);
    int gendata_long_long(metadata *meta);
    int gendata_ulong_long(metadata *meta);
    int gendata_variable(metadata *meta);
    int gendata_object_pointer(metadata *meta);
    int gendata_function_pointer(metadata *meta);
    int gendata_char(metadata *meta);
    int gendata_uchar(metadata *meta);
    int gendata_subroutine(metadata *meta);
    int gendata_pointer(metadata *meta);
    int gendata_reference_count(metadata *meta);
    int gendata_reference(metadata *meta);
    int gendata_const(metadata *meta);
    int gendata_void_const(metadata *meta);
    int gendata_void_pointer(metadata *meta);
    int gendata_boolean(metadata *meta);
    int gendata_member_std_vector_impl(metadata *meta);
    int gendata_enumeration_type(metadata *meta);
    int gendata_enumerator(metadata *meta);
    int gendata_array_type(metadata *meta);
    int gendata_subrange_type(metadata *meta);
    int gendata_unspecified_parameters(metadata *meta);
    int gendata_subroutine_type(metadata *meta); //@}
}

//@}
#endif
